今天繼續來學 gitlab-ci...
圖片來源:Docker (@Docker) / Twitter
上一篇初略寫了 gitlab runner 運作和配置,今天繼續往下~
首先將 harbor 和 gitlab 連接,讓 job 可以直接取得 harbor 配置資訊
我是在 group 直接設定,這樣底下的 project 就不必重新設定了~

目前 group 裡的 project...

前端是一個 react app
三個 stage:
stages:
  - test
  - build
  - integrate
將 node_modules 加入 cache,避免每次都要重新安裝套件
cache:
  paths:
    - node_modules/
執行 unit test
react-app-unit-test:
  stage: test
  image: node:15
  script:
    - npm install
    - npm run test
分為兩個 job
build-react-app:
  stage: build
  image: node:15
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
build-image:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:v1.9.0-debug
    entrypoint: [""]
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"${HARBOR_HOST}\":{\"auth\":\"$(echo -n ${HARBOR_USERNAME}:${HARBOR_PASSWORD} | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
    - >-
      /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "${HARBOR_HOST}/${HARBOR_PROJECT}/${CI_PROJECT_NAME}:${CI_COMMIT_SHORT_SHA}"
      --destination "${HARBOR_HOST}/${HARBOR_PROJECT}/${CI_PROJECT_NAME}:latest"
      --registry-certificate "${HARBOR_HOST}=/etc/gitlab-runner/certs/${HARBOR_HOST}.crt"
呼叫下游的 pipeline 和後端一起執行 integration test
integration-test:
  stage: integrate
  trigger:
    project: test-web/test-web-chart
後端是一個用 express 寫的 server
兩個 stage:
stages:
  - build
  - integrate
打包成 image 上傳到 Harbor
build-image:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:v1.9.0-debug
    entrypoint: [""]
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"${HARBOR_HOST}\":{\"auth\":\"$(echo -n ${HARBOR_USERNAME}:${HARBOR_PASSWORD} | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
    - >-
      /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "${HARBOR_HOST}/${HARBOR_PROJECT}/${CI_PROJECT_NAME}:${CI_COMMIT_SHORT_SHA}"
      --destination "${HARBOR_HOST}/${HARBOR_PROJECT}/${CI_PROJECT_NAME}:latest"
      --registry-certificate "${HARBOR_HOST}=/etc/gitlab-runner/certs/${HARBOR_HOST}.crt"
呼叫下游的 pipeline 和前端一起執行 integration test
integration-test:
  stage: integrate
  trigger:
    project: test-web/test-web-chart
Chart 是用來整合前後端,便於用 helm 部署
在 Kubernetes 先建立一個 ServiceAccount
這裡直接用 cluster-admin 如有安全疑慮可再細部設定
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab-ci
  namespace: gitlab
---
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-ci-secret
  namespace: gitlab
  annotations:
    kubernetes.io/service-account.name: gitlab-ci
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gitlab-ci-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: gitlab-ci
    namespace: gitlab
取得 ServiceAccount token
kubectl get -n gitlab secret/gitlab-ci-secret -o jsonpath='{.data.token}'
接著在 project CI/CD 新增 Variable
DEPLOY_KUBERNETES_BEARER_TOKEN 類型 Variable 並設定為 Masked,將上一步取得的 token 存入DEPLOY_KUBE_CONFIG 類型設定為 File
apiVersion: v1 
kind: Config
clusters:    
- cluster:
    certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    server: https://$${KUBERNETES_SERVICE_HOST}:$${KUBERNETES_SERVICE_PORT}
  name: kubernetes 
contexts:
- context:
    cluster: kubernetes
    namespace: ${CI_PROJECT_NAMESPACE}
    user: gitlab-ci
  name: gitlab@kubernetes
current-context: gitlab@kubernetes
users:
- name: gitlab-ci
  user:
    token: ${DEPLOY_KUBERNETES_BEARER_TOKEN}
我後來才發現 kubernetes 帶入的 env 不能在這裡用... 之後再用 sed 取的就好~
兩個 stage:
stages:
  - build
  - test
將 chart 打包上傳到 Harbor
build-chart:
  stage: build
  image:
    name: alpine/helm:3.10.1
    entrypoint: [""]
  only:
    - pushes
  script:
    - helm plugin install https://github.com/chartmuseum/helm-push
    - >-
      helm repo add
      --username ${HARBOR_USERNAME} 
      --password ${HARBOR_PASSWORD}
      --ca-file /etc/gitlab-runner/certs/ca.crt
      ${HARBOR_PROJECT} https://${HARBOR_HOST}/chartrepo/${HARBOR_PROJECT}
    - helm package ${CI_PROJECT_DIR}
    - helm cm-push --ca-file /etc/gitlab-runner/certs/ca.crt ${CI_PROJECT_DIR} ${HARBOR_PROJECT}
因為使用自簽憑證要再加上
--ca-file
先測試 Kubernetes 連線...
integration-test:
  stage: test
  image: bitnami/kubectl:latest
  script:
    - cat ${DEPLOY_KUBE_CONFIG} > "/.kube/config"
    - sed -i -e "s/\${KUBERNETES_SERVICE_HOST}:\${KUBERNETES_SERVICE_PORT}/${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/" /.kube/config
    - kubectl get pods
因為機器炸了... 只好之後再補部署... 